package stark.app.mine;

import android.content.Context;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.blankj.utilcode.util.UriUtils;
import com.blankj.utilcode.util.Utils;
import com.stark.downloader.Downloader;
import com.stark.downloader.FailCause;

import java.io.File;
import java.io.FileFilter;
import java.io.InputStream;

import io.reactivex.rxjava3.core.ObservableEmitter;
import stark.app.mine.bean.VersionInfo;
import stark.common.basic.utils.IOUtil;
import stark.common.basic.utils.RxUtil;

/**
 * Author：daizhongbin on 2023/5/8
 * Email：1027154338@qq.com
 * Desc:
 */
public class UpgradeManager {

    final String TAG = UpgradeManager.class.getSimpleName();
    static final String VERSION_URL = "http://kmg-server.oss-cn-shenzhen.aliyuncs.com/tmpRes/upgrade/apk/StarkJavaCommon/version.json";
    static final String APK_URL = "http://kmg-server.oss-cn-shenzhen.aliyuncs.com/tmpRes/upgrade/apk/StarkJavaCommon/StarkJavaCommon.apk";
    static final String VERSION_FILE_NAME = "version.json";


    private static UpgradeManager sInstance;

    private UpgradeManager() {
    }

    public static synchronized UpgradeManager getInstance() {
        if (sInstance == null) {
            sInstance = new UpgradeManager();
        }
        return sInstance;
    }

    public void check(ICheckCallback callback) {
        delVersionJsonFile();
        Context context = Utils.getApp();
        Downloader.newTask(context)
                .url(VERSION_URL)
                .fileName(VERSION_FILE_NAME)
                .start(new Downloader.ICallback() {
                    @Override
                    public void onStart(int downloadTaskId) {
                    }

                    @Override
                    public void onProgress(long currentOffset, long totalLength, int percent) {
                    }

                    @Override
                    public void onComplete(@NonNull Uri uri) {
                        try {
                            InputStream is = context.getContentResolver().openInputStream(uri);
                            String json = IOUtil.readStream2Str(is);
                            VersionInfo verInfo = GsonUtils.fromJson(json, VersionInfo.class);
                            int verCode = AppUtils.getAppVersionCode();
                            String pkgName = AppUtils.getAppPackageName();
                            if (verInfo == null ||
                                    TextUtils.isEmpty(verInfo.pkgName) ||
                                    TextUtils.isEmpty(verInfo.verCode)) {
                                ToastUtils.showShort("获取版本信息出错");
                                if (callback != null) {
                                    callback.onCheckSuccess(false, verInfo);
                                }
                                return;
                            }
                            Log.e(TAG, "verInfo = " + verInfo.toString());
                            int newVerCode = Integer.valueOf(verInfo.verCode);
                            boolean hasNewVer = false;
                            if (pkgName.equals(verInfo.pkgName) && newVerCode > verCode) {
                                hasNewVer = true;
                            }
                            if (!hasNewVer) {
                                ToastUtils.showShort("未检测到新版本");
                            }

                            if (callback != null) {
                                callback.onCheckSuccess(hasNewVer, verInfo);
                            }

                        } catch (Exception e) {
                            e.printStackTrace();
                            if (callback != null) {
                                callback.onCheckSuccess(false, null);
                            }
                        }
                    }

                    @Override
                    public void onFail(FailCause cause) {
                        ToastUtils.showShort("下载版本信息失败");
                        if (callback != null) {
                            callback.onCheckSuccess(false, null);
                        }
                    }
                });
    }

    public void downloadApk(VersionInfo verInfo, IDownloadApkCallback callback) {
        Context context = Utils.getApp();
        String fileName = generateApkFileName(verInfo);
        String folder = Downloader.getDownloadFolderInApp();
        String apkFilePath = folder + File.separator + fileName;
        if (FileUtils.isFileExists(apkFilePath)) {
            if (callback != null) {
                callback.onComplete(UriUtils.file2Uri(new File(apkFilePath)));
            }
            return;
        }
        Downloader.newTask(context)
                .url(APK_URL)
                .fileName(fileName)
                .start(new Downloader.ICallback() {
                    @Override
                    public void onStart(int downloadTaskId) {
                    }

                    @Override
                    public void onProgress(long currentOffset, long totalLength, int percent) {
                        if (callback != null) {
                            callback.onProgress(percent);
                        }
                    }

                    @Override
                    public void onComplete(@NonNull Uri uri) {
                        if (callback != null) {
                            callback.onComplete(uri);
                        }
                    }

                    @Override
                    public void onFail(FailCause cause) {
                        //下载失败要删除该文件
                        FileUtils.delete(apkFilePath);
                        if (callback != null) {
                            callback.onFail();
                        }
                    }
                });
    }

    private String generateApkFileName(VersionInfo verInfo) {
        String fileName = verInfo.pkgName.replace(".", "_") + "_ver_" + verInfo.verCode + ".apk";
        return fileName;
    }

    public void init() {
        RxUtil.create(new RxUtil.Callback<Boolean>() {
            @Override
            public void doBackground(ObservableEmitter<Boolean> emitter) {
                clearNoUseFileInDownloadFolder();
                emitter.onNext(true);
            }

            @Override
            public void accept(Boolean obj) {
            }
        });

    }

    private void delVersionJsonFile() {
        try {
            String filePath = Downloader.getDownloadFolderInApp() + File.separator + VERSION_FILE_NAME;
            File file = new File(filePath);
            if (file.exists()) {
                file.delete();
            }
        } catch (Exception e) {

        }
    }

    private void clearNoUseFileInDownloadFolder() {
        String downloadFolder = Downloader.getDownloadFolderInApp();
        File folder = new File(downloadFolder);
        try {
            if (!folder.exists()) return;
            String prefix = AppUtils.getAppPackageName().replace(".", "_") + "_ver_";
            File[] childFiles = folder.listFiles(new FileFilter() {
                @Override
                public boolean accept(File childFile) {
                    String fileName = FileUtils.getFileName(childFile);
                    if (fileName.equals(VERSION_FILE_NAME)) {
                        return true;
                    }

                    if (fileName.startsWith(prefix) && fileName.endsWith(".apk")) {
                        return true;
                    }
                    return false;
                }
            });
            if (childFiles == null || childFiles.length == 0) return;
            String fileName;
            int curVerCode = AppUtils.getAppVersionCode();
            int verCode = 0;
            for (File childFile : childFiles) {
                fileName = FileUtils.getFileName(childFile);
                if (fileName.equals(VERSION_FILE_NAME)) {
                    childFile.delete();
                    continue;
                }
                verCode = parseGetVerCode(fileName);
                if (verCode <= curVerCode) {
                    childFile.delete();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private int parseGetVerCode(String fileName) {
        String[] subStrs = fileName.split("_");
        String lastStr = subStrs[subStrs.length - 1];
        subStrs = lastStr.split("\\.");
        return Integer.parseInt(subStrs[0]);
    }

    public interface ICheckCallback {

        void onCheckSuccess(boolean hasNewVersion, @Nullable VersionInfo versionInfo);

    }

    public interface IDownloadApkCallback {

        void onProgress(int percent);

        void onFail();

        void onComplete(Uri uri);

    }
}
